#include "SSBankQuote.h"

#include <core/strings/string_util.h>

#include "BondContainer.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
// #define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// class CBondBankRep

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBondBankRep::CBondBankRep() {}

CBondBankRep::~CBondBankRep() { Clear(); }

bool CBondBankRep::Clear() {
  std::lock_guard<std::mutex> locker(m_lock);
  m_RepMap.m_map.clear();

  return true;
}

bool CBondBankRep::Clear(int clrFlag) {
  std::lock_guard<std::mutex> locker(m_lock);
  if (clrFlag == CBondContainer::LIQ_CLR_BESTPRICE_ALL) {
    Clear();
  } else {
    std::map<std::string, BKQUOTE>::iterator pos;
    for (pos = m_RepMap.m_map.begin(); pos != m_RepMap.m_map.end();) {
      if (clrFlag == CBondContainer::LIQ_CLR_BESTPRICE_BROKE &&
          pos->first != "e" && pos->first != "c") {
        m_RepMap.m_map.erase(pos++);
      } else if (clrFlag == CBondContainer::LIQ_CLR_BESTPRICE_CFETS &&
                 pos->first == "c") {
        m_RepMap.m_map.erase(pos++);
      } else if (clrFlag == CBondContainer::LIQ_CLR_BESTPRICE_EXCHANGE &&
                 pos->first == "e") {
        m_RepMap.m_map.erase(pos++);
      } else {
        ++pos;
      }
    }
  }
  return true;
}

bool CBondBankRep::InsertBankRep(const BKQUOTE& newElement) {
  std::string strCompId = newElement.m_BCCompanyID;

  std::lock_guard<std::mutex> locker(m_lock);

  m_RepMap.m_map[strCompId] = newElement;

  return true;
}

bool CBondBankRep::GetBankRepByKey(const std::string& sKey, BKQUOTE& stRep) {
  std::lock_guard<std::mutex> locker(m_lock);

  if (m_RepMap.m_map.size() == 0) return false;

  std::map<std::string, BKQUOTE>::iterator itr = m_RepMap.m_map.find(sKey);
  if (itr != m_RepMap.m_map.end()) {
    stRep = itr->second;
    return true;
  }

  return false;
}

void CBondBankRep::ApplyAccess(bool all, const std::string& sKey,
                               ApplyCallback* callback) {
  std::lock_guard<std::mutex> locker(m_lock);
  if (all) {
    std::map<std::string, BKQUOTE>::iterator it = m_RepMap.m_map.begin();
    for (; it != m_RepMap.m_map.end(); ++it) {
      if (!callback->DoAccess(it->second)) break;
    }
  } else {
    std::map<std::string, BKQUOTE>::iterator it = m_RepMap.m_map.find(sKey);
    if (it != m_RepMap.m_map.end()) callback->DoAccess(it->second);
  }
}
void CBondBankRep::ApplyModify(bool all, const std::string& sKey,
                               ApplyCallback* callback) {
  std::lock_guard<std::mutex> locker(m_lock);
  if (all) {
    std::map<std::string, BKQUOTE>::iterator it = m_RepMap.m_map.begin();
    for (; it != m_RepMap.m_map.end(); ++it) {
      if (!callback->DoModify(it->second)) break;
    }
  } else {
    std::map<std::string, BKQUOTE>::iterator it = m_RepMap.m_map.find(sKey);
    if (it != m_RepMap.m_map.end()) callback->DoModify(it->second);
  }
}

int CBondBankRep::GetSize() const {
  std::lock_guard<std::mutex> locker(const_cast<std::mutex&>(m_lock));

  return m_RepMap.m_map.size();
}

const char* CBondBankRep::GetName() const { return "CBondBankRep"; }

int CBondBankRep::GetBytes(int mode) const {
  std::lock_guard<std::mutex> locker(const_cast<std::mutex&>(m_lock));
  int bytes = 0;
  if (mode == 0) {
    bytes = (sizeof(std::map<std::string, BKQUOTE>::value_type) -
             sizeof(std::string)) *
            m_RepMap.m_map.size();
    std::map<std::string, BKQUOTE>::const_iterator it = m_RepMap.m_map.begin();
    for (; it != m_RepMap.m_map.end(); ++it) {
      bytes += qb::base::StringUtil::GetStringAllBytes(it->first);
    }
  } else {
    bytes = sizeof(BKQUOTE) * m_RepMap.m_map.size();
    std::map<std::string, BKQUOTE>::const_iterator it = m_RepMap.m_map.begin();
    for (; it != m_RepMap.m_map.end(); ++it) {
      bytes += qb::base::StringUtil::GetStringRealBytes(it->first);
    }
  }
  return bytes;
}
